Avasta TypeScripti võimsad malli literaaltüübid täiustatud stringi manipuleerimiseks, mustrite sobitamiseks ja valideerimiseks. Õpi praktiliste näidete ja reaalsete kasutusjuhtumite abil.
Malli literaaltüübid: stringimustrite sobitamine ja valideerimine TypeScriptis
TypeScripti tüübisüsteem areneb pidevalt, pakkudes arendajatele võimsamaid tööriistu keeruka loogika väljendamiseks ja tüübiohutuse tagamiseks. Üks huvitavamaid ja mitmekülgsemaid funktsioone, mis viimastes versioonides kasutusele võeti, on malli literaaltüübid. Need tüübid võimaldavad manipuleerida stringe tüübitasandil, võimaldades täiustatud stringimustrite sobitamist ja valideerimist. See avab täiesti uue võimaluste maailma robustsemate ja hooldatavamate rakenduste loomiseks.
Mis on malli literaaltüübid?
Malli literaaltüübid on tüübi vorm, mis on konstrueeritud stringi literaaltüüpide ja ühendtüüpide kombineerimisel, sarnaselt sellele, kuidas malli literaalid JavaScriptis töötavad. Kuid selle asemel, et luua käitusaja stringe, loovad nad uusi tüüpe olemasolevate põhjal.
Siin on lihtne näide:
type Greeting<T extends string> = `Hello, ${T}!`;
type MyGreeting = Greeting<"World">; // type MyGreeting = "Hello, World!"
Selles näites on `Greeting` malli literaaltüüp, mis võtab sisendiks stringitüübi `T` ja tagastab uue tüübi, mis on "Hello, ", `T` ja "!" aheldamine.
Stringimustrite lihtne sobitamine
Malli literaaltüüpe saab kasutada stringimustrite lihtsaks sobitamiseks. See võimaldab luua tüüpe, mis on kehtivad ainult siis, kui need vastavad kindlale mustrile.
Näiteks saate luua tüübi, mis aktsepteerib ainult stringe, mis algavad "prefix-":
type PrefixedString<T extends string> = T extends `prefix-${string}` ? T : never;
type ValidPrefixedString = PrefixedString<"prefix-valid">; // type ValidPrefixedString = "prefix-valid"
type InvalidPrefixedString = PrefixedString<"invalid">; // type InvalidPrefixedString = never
Selles näites kasutab `PrefixedString` tingimustüüpi, et kontrollida, kas sisendstring `T` algab "prefix-". Kui see algab, on tüüp `T` ise; vastasel juhul on see `never`. `never` on TypeScriptis eriline tüüp, mis esindab väärtuste tüüpi, mis kunagi ei esine, välistades seega kehtetu stringi.
Stringi osade eraldamine
Malli literaaltüüpe saab kasutada ka stringi osade eraldamiseks. See on eriti kasulik, kui teil on vaja stringidest andmeid parsida ja teisendada need erinevateks tüüpideks.
Oletame, et teil on string, mis esindab koordinaati vormingus "x:10,y:20". Saate kasutada malli literaaltüüpe x- ja y-väärtuste eraldamiseks:
type CoordinateString = `x:${number},y:${number}`;
type ExtractX<T extends CoordinateString> = T extends `x:${infer X},y:${number}` ? X : never;
type ExtractY<T extends CoordinateString> = T extends `x:${number},y:${infer Y}` ? Y : never;
type XValue = ExtractX<"x:10,y:20">; // type XValue = 10
type YValue = ExtractY<"x:10,y:20">; // type YValue = 20
Selles näites kasutavad `ExtractX` ja `ExtractY` märksõna `infer`, et hõivata stringi osi, mis vastavad `number` tüübile. `infer` võimaldab teil mustri sobitamisest tüüpi eraldada. Hõivatud tüüpe kasutatakse seejärel tingimustüübi tagastustüübina.
Täiustatud stringi valideerimine
Malli literaaltüüpe saab kombineerida teiste TypeScripti funktsioonidega, nagu ühendtüübid ja tingimustüübid, et teostada täiustatud stringi valideerimist. See võimaldab luua tüüpe, mis jõustavad keerulisi reegleid stringide struktuurile ja sisule.
Näiteks saate luua tüübi, mis valideerib ISO 8601 kuupäevastringe:
type Year = `${number}${number}${number}${number}`;
type Month = `0${number}` | `10` | `11` | `12`;
type Day = `${0}${number}` | `${1 | 2}${number}` | `30` | `31`;
type ISODate = `${Year}-${Month}-${Day}`;
type ValidDate = ISODate extends "2023-10-27" ? true : false; // true
type InvalidDate = ISODate extends "2023-13-27" ? true : false; // false
function processDate(date: ISODate) {
// Function logic here. TypeScript enforces the ISODate format.
return `Processing date: ${date}`;
}
console.log(processDate("2024-01-15")); // Works
//console.log(processDate("2024-1-15")); // TypeScript error: Argument of type '"2024-1-15"' is not assignable to parameter of type '`${number}${number}${number}${number}-${0}${number}-${0}${number}` | `${number}${number}${number}${number}-${0}${number}-${1}${number}` | ... 14 more ... | `${number}${number}${number}${number}-12-31`'.
Siin on `Year`, `Month` ja `Day` defineeritud malli literaaltüüpide abil, et esindada iga kuupäeva osa kehtivaid vorminguid. Seejärel kombineerib `ISODate` need tüübid, et luua tüüp, mis esindab kehtivat ISO 8601 kuupäevastringi. Näide demonstreerib ka seda, kuidas seda tüüpi saab kasutada funktsioonis andmete vormindamise jõustamiseks, vältides valede kuupäevavormingute edastamist. See parandab koodi usaldusväärsust ja hoiab ära käitusaja vead, mis on põhjustatud ebaõigest sisendist.
Reaalse maailma kasutusjuhud
Malli literaaltüüpe saab kasutada mitmesugustes reaalmaailma stsenaariumides. Siin on mõned näited:
- Vormi valideerimine: Malli literaaltüüpe saate kasutada vormi sisendite vormingu valideerimiseks, näiteks e-posti aadresside, telefoninumbrite ja sihtnumbrite puhul.
- API päringu valideerimine: Malli literaaltüüpe saate kasutada API päringute sisu struktuuri valideerimiseks, tagades, et need vastavad oodatud vormingule. Näiteks valuutakoodi valideerimine (nt "USD", "EUR", "GBP").
- Konfiguratsioonifaili parsermine: Malli literaaltüüpe saate kasutada konfiguratsioonifailide parsermiseks ja väärtuste eraldamiseks konkreetsete mustrite alusel. Mõelge failiteede valideerimisele konfiguratsiooniobjektis.
- Stringipõhised enumsid: Stringipõhiseid enumse saab luua valideerimisega, kasutades malli literaaltüüpe.
Näide: Valuutakoodide valideerimine
Vaatame lähemalt valuutakoodide valideerimise näidet. Tahame tagada, et meie rakenduses kasutatakse ainult kehtivaid ISO 4217 valuutakoode. Need koodid koosnevad tavaliselt kolmest suurtähest.
type CurrencyCode = `${Uppercase<string>}${Uppercase<string>}${Uppercase<string>}`;
function formatCurrency(amount: number, currency: CurrencyCode) {
// Function logic to format currency based on the provided code.
return `$${amount} ${currency}`;
}
console.log(formatCurrency(100, "USD")); // Works
//console.log(formatCurrency(100, "usd")); // TypeScript error: Argument of type '"usd"' is not assignable to parameter of type '`${Uppercase<string>}${Uppercase<string>}${Uppercase<string>}`'.
//More precise example:
type ValidCurrencyCode = "USD" | "EUR" | "GBP" | "JPY" | "CAD" | "AUD"; // Extend as needed
type StronglyTypedCurrencyCode = ValidCurrencyCode;
function formatCurrencyStronglyTyped(amount: number, currency: StronglyTypedCurrencyCode) {
return `$${amount} ${currency}`;
}
console.log(formatCurrencyStronglyTyped(100, "EUR")); // Works
//console.log(formatCurrencyStronglyTyped(100, "CNY")); // TypeScript error: Argument of type '"CNY"' is not assignable to parameter of type '"USD" | "EUR" | "GBP" | "JPY" | "CAD" | "AUD"'.
See näide demonstreerib, kuidas luua `CurrencyCode` tüüp, mis aktsepteerib ainult kolmest suurtähest koosnevaid stringe. Teine, rangemalt tüübistatud näide näitab, kuidas seda veelgi piirata eeldefineeritud aktsepteeritavate valuutade loendiga.
Näide: API otspunkti teede valideerimine
Teine kasutusjuhtum on API otspunkti teede valideerimine. Saate määratleda tüübi, mis esindab kehtivat API otspunkti struktuuri, tagades, et päringud tehakse õigetele teedele. See on eriti kasulik mikroteenuste arhitektuurides, kus mitmed teenused võivad pakkuda erinevaid API-sid.
type APIServiceName = "users" | "products" | "orders";
type APIEndpointPath = `/${APIServiceName}/${string}`;
function callAPI(path: APIEndpointPath) {
// API call logic
console.log(`Calling API: ${path}`);
}
callAPI("/users/123"); // Valid
callAPI("/products/details"); // Valid
//callAPI("/invalid/path"); // TypeScript error
// Even more specific:
type APIAction = "create" | "read" | "update" | "delete";
type APIEndpointPathSpecific = `/${APIServiceName}/${APIAction}`;
function callAPISpecific(path: APIEndpointPathSpecific) {
// API call logic
console.log(`Calling specific API: ${path}`);
}
callAPISpecific("/users/create"); // Valid
//callAPISpecific("/users/list"); // TypeScript error
See võimaldab teil API otspunktide struktuuri täpsemalt määratleda, vältides trükivigu ja tagades järjepidevuse kogu rakenduses. See on lihtne näide; keerukamaid mustreid saab luua päringuparameetrite ja muude URL-i osade valideerimiseks.
Malli literaaltüüpide kasutamise eelised
- Parem tüübiohutus: Malli literaaltüübid võimaldavad jõustada stringidele rangemaid tüübipiiranguid, vähendades käitusaja vigade riski.
- Parem koodi loetavus: Malli literaaltüübid muudavad teie koodi loetavamaks, väljendades selgelt stringide oodatavat vormingut.
- Suurem hooldatavus: Malli literaaltüübid muudavad teie koodi hooldatavamaks, pakkudes stringi valideerimisreeglitele ühtset tõeallikat.
- Parem arendajakogemus: Malli literaaltüübid pakuvad paremat automaatset lõpetamist ja veateateid, parandades üldist arendajakogemust.
Piirangud
- Keerukus: Malli literaaltüübid võivad muutuda keerukaks, eriti keeruliste mustritega tegelemisel. Oluline on tasakaalustada tüübiohutuse eeliseid koodi hooldatavusega.
- Jõudlus: Malli literaaltüübid võivad mõjutada kompileerimise jõudlust, eriti suurtes projektides. Seda seetõttu, et TypeScript peab teostama keerukamat tüübikontrolli.
- Piiratud regulaaravaldiste tugi: Kuigi malli literaaltüübid võimaldavad mustrite sobitamist, ei toeta need kogu regulaaravaldiste funktsioonide spektrit. Väga keerulise stringi valideerimise puhul võib lisaks nendele tüübikonstruktidele endiselt vaja minna käitusaja regulaaravaldisi sisendi korrektseks sanitaarseks töötlemiseks.
Parimad tavad
- Alusta lihtsast: Alustage lihtsate mustritega ja suurendage keerukust järk-järgult vastavalt vajadusele.
- Kasuta kirjeldavaid nimesid: Kasutage oma malli literaaltüüpide jaoks kirjeldavaid nimesid, et parandada koodi loetavust.
- Dokumenteeri oma tüübid: Dokumenteeri oma malli literaaltüübid, et selgitada nende eesmärki ja kasutust.
- Testi põhjalikult: Testi oma malli literaaltüüpe põhjalikult, et veenduda, et need käituvad ootuspäraselt.
- Arvesta jõudlusega: Pidage meeles malli literaaltüüpide mõju kompileerimise jõudlusele ja optimeerige oma koodi vastavalt.
Kokkuvõte
Malli literaaltüübid on TypeScripti võimas funktsioon, mis võimaldab teostada täiustatud stringi manipuleerimist, mustrite sobitamist ja valideerimist tüübitasandil. Malli literaaltüüpide abil saate luua robustsemaid, hooldatavamaid ja tüübiohuseid rakendusi. Kuigi neil on mõned piirangud, kaaluvad malli literaaltüüpide kasutamise eelised sageli üles puudused, muutes need väärtuslikuks tööriistaks iga TypeScripti arendaja arsenalis. Kuna TypeScripti keel areneb jätkuvalt, on nende täiustatud tüübifunktsioonide mõistmine ja kasutamine kvaliteetse tarkvara loomisel ülioluline. Ärge unustage tasakaalustada keerukust loetavusega ja alati eelistada põhjalikku testimist.